home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconify-source.lzh / Source / wScreen.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  14KB  |  474 lines

  1. /*
  2.  *  WICONIFY    A utility that allows you to iconify any Intuition window
  3.  *              on any screen, and to open WB windows on any screen.
  4.  *
  5.  *  wScreen.c   Handles menu and screen functions.
  6.  *
  7.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  8.  *  You may use this code, provided this copyright notice is kept intact.
  9.  */
  10.  
  11. #define INTUITION_PREFERENCES_H             /* don't need 'em */
  12. #include <intuition/intuitionbase.h>
  13. #include <libraries/dosextens.h>
  14. #include "wHandler.h"
  15. #include "wMenu.h"
  16.  
  17.  
  18. #define SCREENMEM(p)    RASSIZE(p.Width,p.Height*p.Depth)
  19.  
  20. #define RED(i)          (((Color[i])>>8)&0x0F)
  21. #define GREEN(i)        (((Color[i])>>4)&0x0F)
  22. #define BLUE(i)         ( (Color[i])    &0x0F)
  23.  
  24. /*
  25.  *  The newScreen structure for wIconify screens
  26.  */
  27. static struct NewScreen IconScreen =
  28.    {0,0, 640,200,2, 0,1, HIRES,CUSTOMSCREEN, NULL,"wIconify Screen",NULL,NULL};
  29.  
  30. static struct Window *PreviousWindow;
  31.  
  32. static char *LockName = "UnLock";
  33. extern struct wMenuItem OpenWindowMenu[],
  34.                         NewScreenMenu[],
  35.                         IconMenu[],
  36.                         ScreenMenu[];
  37.  
  38. /*
  39.  *  Macros for modifying the menus during menu update
  40.  */
  41. #define ENABLESCREEN(n)     ScreenMenu[n].Item.Flags |=  ITEMENABLED
  42. #define DISABLESCREEN(n)    ScreenMenu[n].Item.Flags &= ~ITEMENABLED
  43. #define ENABLEICON(n)       IconMenu[n].Item.Flags |=  ITEMENABLED
  44. #define DISABLEICON(n)      IconMenu[n].Item.Flags &= ~ITEMENABLED
  45. #define CHECKITEM(n)        NewScreenMenu[n].Item.Flags |=  CHECKED
  46. #define UNCHECKITEM(n)      NewScreenMenu[n].Item.Flags &= ~CHECKED
  47. #define ISCHECKED(n)        (NewScreenMenu[n].Item.Flags & CHECKED)
  48. #define SETLOCK(n)\
  49.    (((struct IntuiText *)(IconMenu[n].Item.ItemFill))->IText = &LockName[2])
  50. #define SETUNLOCK(n)\
  51.    (((struct IntuiText *)(IconMenu[n].Item.ItemFill))->IText = LockName)
  52.  
  53.  
  54. /*
  55.  *  SetScreenMenu()
  56.  *
  57.  *  Check the correct HIRES/LORES menu
  58.  *  Check or uncheck the INTERLACE and HAM menus
  59.  */
  60.  
  61. void SetScreenMenu(Modes)
  62. UWORD Modes;
  63. {
  64.    if (Modes & HIRES)
  65.    {
  66.       CHECKITEM(NS_HIRES);
  67.       UNCHECKITEM(NS_LORES);
  68.    } else {
  69.       CHECKITEM(NS_LORES);
  70.       UNCHECKITEM(NS_HIRES);
  71.    }
  72.    if (Modes & LACE) CHECKITEM(NS_INTERLACE); else UNCHECKITEM(NS_INTERLACE);
  73.    if (Modes & HAM)  CHECKITEM(NS_HAM);       else UNCHECKITEM(NS_HAM);
  74. }
  75.  
  76.  
  77. /*
  78.  *  SetActiveMenu()
  79.  *
  80.  *  Get the screen from the backdrop window
  81.  *  If the screen is the RealWB, don't allow it to be iconified
  82.  *  If the screen is the current WB or it is in the process of closing
  83.  *    or real WB is the current WB and so is the screen we are using
  84.  *      don't allow the MAKEWB menu
  85.  *  Don't allow the CLOSESCREEN item, unless...
  86.  *  If the screen is a wIconify screen and it has no windows
  87.  *    And the only icons on the screen are AUTOREMOVE icons
  88.  *      Then allow CLOSESCREEN
  89.  *  If the active backdrop window has changed, update the NEWSCREEN menus
  90.  *  If there are icons on the screen
  91.  *    Enable CLEANUP, ORGANIZE and OPENALL
  92.  *  Otherwise disable them
  93.  *  Disable the CLOSE item, unless...
  94.  *  If there are selected icons
  95.  *    Enable OPEN and UNLOCK and disable CLEANUP, unless..
  96.  *    While ther eare more selected gadgets
  97.  *      If the gadget is allowed to be close, enable CLOSE
  98.  *      If the gadget is not locked
  99.  *        Set the UNLOCK menu to LOCK
  100.  *        If the icon can be organized, enable CLEANUP
  101.  *      Go on to the next selected icon
  102.  *  Otherwise (no selected icons) disable OPEN and LOCK
  103.  *  If the screen can hold the tallest menu, set the menu strip
  104.  */
  105.  
  106. static void SetActiveMenu(theWindow)
  107. struct Window *theWindow;
  108. {
  109.    WSCREEN *theScreen;
  110.    WICONREF *theIcon;
  111.    struct wGadget *theGadget;
  112.  
  113.    Forbid();
  114.    theScreen = (WSCREEN *)theWindow->UserData;
  115.    if (theScreen == RealWB) DISABLESCREEN(SM_ICONIFY);
  116.       else ENABLESCREEN(SM_ICONIFY);
  117.    if (theScreen == WBScreen || (theScreen->Flags & WI_CLOSING) ||
  118.       (WBScreen == NULL && theScreen == RealWB))
  119.           DISABLESCREEN(SM_MAKEWB); else ENABLESCREEN(SM_MAKEWB);
  120.    DISABLESCREEN(SM_CLOSESCREEN);
  121.    if ((theScreen->Flags & WI_WSCREEN) && theScreen->Window == NULL)
  122.    {
  123.       theIcon = theScreen->IconRef;
  124.       while (theIcon && ((theIcon->Icon.Flags & WI_AUTOREMOVE)))
  125.          theIcon = theIcon->Next;
  126.       if (theIcon == NULL) ENABLESCREEN(SM_CLOSESCREEN);
  127.    }
  128.    if (ActiveWindow != PreviousWindow)
  129.       SetScreenMenu(theScreen->Screen->ViewPort.Modes);
  130.  
  131.    if (theScreen->BackDrop->FirstGadget)
  132.    {
  133.       ENABLEICON(IM_CLEANUP);
  134.       ENABLEICON(IM_ORGANIZE);
  135.       ENABLEICON(IM_OPENALL);
  136.    } else {
  137.       DISABLEICON(IM_CLEANUP);
  138.       DISABLEICON(IM_ORGANIZE);
  139.       DISABLEICON(IM_OPENALL);
  140.    }
  141.    DISABLEICON(IM_CLOSE);
  142.    if (theScreen->Selected)
  143.    {
  144.       ENABLEICON(IM_OPEN);
  145.       ENABLEICON(IM_LOCK); SETUNLOCK(IM_LOCK);
  146.       DISABLEICON(IM_CLEANUP);
  147.       theGadget = theScreen->Selected;
  148.       while (theGadget)
  149.       {
  150.          if ((GADGETICON->Icon.Flags & WI_NOCLOSE) == FALSE)
  151.             ENABLEICON(IM_CLOSE);
  152.          if ((GADGETICON->Icon.Flags & WI_LOCKED) == FALSE)
  153.          {
  154.             SETLOCK(IM_LOCK);
  155.             if ((GADGETICON->Icon.Flags & WI_NOORGANIZE) == FALSE)
  156.                ENABLEICON(IM_CLEANUP);
  157.          }
  158.          theGadget = theGadget->NextSelect;
  159.       }
  160.    } else {
  161.       DISABLEICON(IM_OPEN);
  162.       DISABLEICON(IM_LOCK); SETLOCK(IM_LOCK);
  163.    }
  164.    Permit();
  165.    if (theScreen->Screen->Height >= TOTAL_MENUH)
  166.       SetMenuStrip(ActiveWindow,wMenu);
  167. }
  168.  
  169.  
  170. /*
  171.  *  SetWindowMenu()
  172.  *
  173.  *  If a backdrop window is active, remove its menu strip
  174.  *  If the OpenOn type has changed
  175.  *    Check and uncheck the correct items in the menu
  176.  *  If SizeToFit has changed
  177.  *    Check or uncheck it
  178.  *  If a backdrop window was active, add the menu strip again
  179.  */
  180.  
  181. void SetWindowMenu(ScreenType,SizeToFit)
  182. int ScreenType,SizeToFit;
  183. {
  184.    short i;
  185.  
  186.    if (ActiveWindow) ClearMenuStrip(ActiveWindow);
  187.    Forbid();
  188.    if (ScreenType != NOCHANGE)
  189.    {
  190.       for (i=OW_ACTIVESCRN; i<=OW_REALWB; i++)
  191.       {
  192.          if (i == ScreenType)
  193.            OpenWindowMenu[i].Item.Flags |=  CHECKED;
  194.           else
  195.            OpenWindowMenu[i].Item.Flags &= ~CHECKED;
  196.       }
  197.    }
  198.    if (SizeToFit != NOCHANGE)
  199.    {
  200.       if (SizeToFit)
  201.          OpenWindowMenu[OW_AUTORESIZE].Item.Flags |=  CHECKED;
  202.         else
  203.          OpenWindowMenu[OW_AUTORESIZE].Item.Flags &= ~CHECKED;
  204.    }
  205.    Permit();
  206.    if (ActiveWindow) SetActiveMenu(ActiveWindow);
  207. }
  208.  
  209.  
  210. /*
  211.  *  SetActiveWindow()
  212.  *
  213.  *  If the window is not already the active one
  214.  *    If there is an old active one
  215.  *      Get the window's screen
  216.  *      If it has icons that are being dragged, cancel the dragging
  217.  *      Remove the menu strip
  218.  *      Report that the icon window is becoming inactive to anyone who cares
  219.  *    Set the new active window
  220.  *    If there is a new window
  221.  *      Clear any error message from the title
  222.  *      Setup the menu strip and add it
  223.  *      Record the fact that this was the last window active
  224.  *      Report the activation to anyone who wants to know
  225.  */
  226.  
  227. void SetActiveWindow(theWindow)
  228. struct Window *theWindow;
  229. {
  230.    WSCREEN *theScreen;
  231.  
  232.    if (theWindow != ActiveWindow)
  233.    {
  234.       if (ActiveWindow)
  235.       {
  236.          theScreen = (WSCREEN *)ActiveWindow->UserData;
  237.          if (theScreen->Flags & (WI_STARTDRAG| WI_DRAGGING))
  238.              CancelDragging(theScreen);
  239.          ClearMenuStrip(ActiveWindow);
  240.          ReportMulti(WI_REPORTINACTIVE,ActiveWindow,theScreen);
  241.       }
  242.       ActiveWindow = theWindow;
  243.       if (ActiveWindow)
  244.       {
  245.          if (ActiveWindow->ScreenTitle != wIconifyTitle)
  246.             SetWindowTitles(ActiveWindow,-ONE,wIconifyTitle);
  247.          SetActiveMenu(ActiveWindow);
  248.          PreviousWindow = ActiveWindow;
  249.          ReportMulti(WI_REPORTACTIVATE,ActiveWindow,ActiveWindow->UserData);
  250.       }
  251.    }
  252. }
  253.  
  254.  
  255. /*
  256.  *  UpdateActiveMenu()
  257.  *
  258.  *  If there is an active window
  259.  *    Remove its menu, then set up and add the menu again
  260.  */
  261.  
  262. void UpdateActiveMenu()
  263. {
  264.    if (ActiveWindow)
  265.    {
  266.       ClearMenuStrip(ActiveWindow);
  267.       SetActiveMenu(ActiveWindow);
  268.    }
  269. }
  270.  
  271.  
  272. /*
  273.  *  SetScreenColors()
  274.  *
  275.  *  If the new scren depth is too big, clip it
  276.  *  For each color in the map, if no color was specified
  277.  *    Get it from the screen's color map (always should be the same)
  278.  *  Set the screen's color map to the specified colors
  279.  */
  280.  
  281. static void SetScreenColors(theScreen)
  282. struct Screen *theScreen;
  283. {
  284.    short i;
  285.    struct ViewPort *theVP = &(theScreen->ViewPort);
  286.    short Depth = (1 << theScreen->BitMap.Depth);
  287.    
  288.    if (Depth > 32) Depth = 32;
  289.    for (i=0; i<Depth; i++)
  290.       if (Colors[i] == NOCOLOR) Colors[i] = GetRGB4(theVP->ColorMap,i);
  291.    LoadRGB4(theVP,&Colors[0],Depth);
  292. }
  293.  
  294.  
  295. /*
  296.  *  DoNewScreen()
  297.  *
  298.  *  Set the modes and width from the current screen according to whether
  299.  *    the new screen should be HIRES or not
  300.  *  Set the modes and height from the current screen according to whether
  301.  *    the new screen should be interlaced or not
  302.  *  Set the modes and depth for HAM screens
  303.  *  If there is enough CHIP memory for the screen plus some extra,
  304.  *    Attempt to open the screen
  305.  *    If successful
  306.  *      Set the new screen's color map
  307.  *      If the screen got a wIconify backdrop window (usually should)
  308.  *        Set the screen as a wIconify screen and as the new WB screen
  309.  *  Otherwise give an error
  310.  */
  311.  
  312. WSCREEN *DoNewScreen(Depth,oldScreen)
  313. UWORD Depth;
  314. struct Screen *oldScreen;
  315. {
  316.    struct Screen *newScreen;
  317.    WSCREEN *theScreen = NULL;
  318.    UWORD Modes = oldScreen->ViewPort.Modes;
  319.    extern long AvailMem();
  320.    
  321.    if (ISCHECKED(NS_HIRES))
  322.    {
  323.       IconScreen.ViewModes |= HIRES;
  324.       IconScreen.Width = (Modes & HIRES)? oldScreen->Width: oldScreen->Width*2;
  325.       if (Depth > 4) Depth = 4;
  326.    } else {
  327.       IconScreen.ViewModes &= ~HIRES;
  328.       IconScreen.Width = (Modes & HIRES)? oldScreen->Width/2: oldScreen->Width;
  329.    }
  330.    if (ISCHECKED(NS_INTERLACE))
  331.    {
  332.       IconScreen.ViewModes |= LACE;
  333.       IconScreen.Height = (Modes&LACE)? oldScreen->Height: oldScreen->Height*2;
  334.    } else {
  335.       IconScreen.ViewModes &= ~LACE;
  336.       IconScreen.Height = (Modes&LACE)? oldScreen->Height/2: oldScreen->Height;
  337.    }
  338.    if (ISCHECKED(NS_HAM))
  339.    {
  340.       IconScreen.ViewModes |= HAM;
  341.       Depth = 6;
  342.    } else {
  343.       IconScreen.ViewModes &= ~HAM;
  344.    }
  345.    IconScreen.Depth = Depth;
  346.    if (AvailMem(MEMF_CHIP) > 125 * SCREENMEM(IconScreen) / 100)
  347.    {
  348.       newScreen = OpenScreen(&IconScreen);
  349.       if (newScreen)
  350.       {
  351.          SetScreenColors(newScreen);
  352.          if (theScreen = FindScreen(newScreen))
  353.          {
  354.             theScreen->Flags |= WI_WSCREEN;
  355.             NewWBScreen(theScreen);
  356.          }
  357.       } else IconError("Can't open New Screen");
  358.    } else IconError("Too low on memory to open New Screen");
  359.    return(theScreen);
  360. }
  361.  
  362.  
  363. /*
  364.  *  DoScreenMenu()
  365.  *
  366.  *  Do the right thing for each Screen menu item:
  367.  *    SCREENTOFRONT:
  368.  *      Send the screen to the front and activate it's backdrop
  369.  *    SCREENTOBACK:
  370.  *      Find the screen following this one
  371.  *      Send the screen to the back
  372.  *      If the following screen has a backdrop window, activate it
  373.  *    WBTOFRONT:
  374.  *      Get the current WB screen and bring it to the front
  375.  *      Activate its backdrop, if any
  376.  *    TOGGLETITLE:
  377.  *      Toggle the title for the screen
  378.  *    ICONIFY:
  379.  *      Set up a bogus message and call the Iconify routine to iconify it
  380.  *    MAKEWB:
  381.  *      Set the screen as the new WB screen
  382.  *      Activate the CurrentWB menu item
  383.  *    NEWCLI:
  384.  *      Create the NewCLI
  385.  *    NEWSCREEN:
  386.  *      Get the subcode
  387.  *      If it is a depth code
  388.  *        Create a new screen of the proper depth
  389.  *        If the screen was created and it has a backdrop window, activate it
  390.  *    CLOSESCREEN:
  391.  *      If the screen is a wIconify screen and it has no windows open on it
  392.  *        Report the screen close to those interested in it
  393.  *          (some icons may choose to close themselves)
  394.  *        Remove the auto-remove icons
  395.  *        If there are no icons left close the screen
  396.  */
  397.  
  398. int DoScreenMenu(theCode,theScreen,EndItAll)
  399. USHORT theCode;
  400. WSCREEN *theScreen;
  401. int EndItAll;
  402. {
  403.    struct Screen *nextScreen;
  404.    struct wIconMessage tmpMessage;
  405.  
  406.    switch(ITEMNUM(theCode))
  407.    {
  408.       case SM_TOFRONT:
  409.          ScreenToFront(theScreen->Screen);
  410.          ActivateWindow(theScreen->BackDrop);
  411.          break;
  412.  
  413.       case SM_TOBACK:
  414.          Forbid(); nextScreen = IntuitionBase->FirstScreen; Permit();
  415.          if (nextScreen == theScreen->Screen)
  416.             nextScreen = nextScreen->NextScreen;
  417.          ScreenToBack(theScreen->Screen);
  418.          theScreen = FindScreen(nextScreen);
  419.          if (theScreen && theScreen->BackDrop)
  420.             ActivateWindow(theScreen->BackDrop);
  421.          break;
  422.  
  423.       case SM_WBTOFRONT:
  424.          if (WBScreen) theScreen = WBScreen; else theScreen = RealWB;
  425.          ScreenToFront(theScreen->Screen);
  426.          if (theScreen->BackDrop) ActivateWindow(theScreen->BackDrop);
  427.          break;
  428.  
  429.       case SM_TOGGLE:
  430.          if (theScreen->Screen->Flags & SHOWTITLE)
  431.              ShowTitle(theScreen->Screen,FALSE);
  432.             else
  433.              ShowTitle(theScreen->Screen,TRUE);
  434.          break;
  435.  
  436.       case SM_ICONIFY:
  437.          tmpMessage.Action = WI_ICONIFY;
  438.          tmpMessage.Window = theScreen->BackDrop;
  439.          tmpMessage.Flags = 0;
  440.          DoIconify(&tmpMessage);
  441.          break;
  442.  
  443.       case SM_MAKEWB:
  444.          NewWBScreen(theScreen);
  445.          SetWindowMenu(OW_CURRENTWB,NOCHANGE);
  446.          break;
  447.  
  448.       case SM_NEWCLI:
  449.          DoNewCLI(theScreen);
  450.          break;
  451.  
  452.       case SM_NEWSCREEN:
  453.          theCode = SUBNUM(theCode);
  454.          if (theCode >= NS_DEPTH1 && theCode <= NS_DEPTH5)
  455.          {
  456.             theScreen = DoNewScreen(theCode-NS_DEPTH1+1,theScreen->Screen);
  457.             if (theScreen && theScreen->BackDrop)
  458.                ActivateWindow(theScreen->BackDrop);
  459.          }
  460.          break;
  461.  
  462.       case SM_CLOSESCREEN:
  463.          if ((theScreen->Flags & WI_WSCREEN) && theScreen->Window == NULL)
  464.          {
  465.             ReportMulti(WI_REPORTSCREENCLOSE,theScreen->Screen,theScreen);
  466.             RemoveAutoIcons(theScreen);
  467.             if (theScreen->IconRef == NULL) CloseScreen(theScreen->Screen);
  468.          }
  469.          break;
  470.    }
  471.    Permit();
  472.    return(EndItAll);
  473. }
  474.